package cn.itsource.user.service.impl;

import cn.itsource.user.domain.User;
import cn.itsource.user.domain.vo.UserVo;
import cn.itsource.user.service.ICodeService;
import cn.itsource.user.service.IUserService;
import cn.itsource.utils.StrUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class CodeServiceImpl implements ICodeService {
    @Autowired
    private IUserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void sendCode(UserVo userVo) throws Exception{
        //1.根据手机号 查询 用户是否注册
        if (userVo.getCodeType().equals("REGISTER")){//当前的操作是用户注册
            User user = userService.loadByPhone(userVo.getPhone());
            if (user!=null){ //用户已经存在
                //【2.如果注册，直接抛异常】
                throw  new RuntimeException("手机号已经注册，请求直接登录");
            }
        }
        /*
            1.判断同一个手机号距离上一次请求是否间隔了一分钟
                在一分钟内：不合法的请求
                超过一分钟：合法的请求

            解决方案：
                1. redis里面 数据存储的时候 有一个过期时间
                如果根据手机号获取 拿不到验证码  或者 过期时间小于4分钟 就是合法的请求
                2.在存储数据的时候，顺便存储一个存储时间
                   根据手机号获取 拿不到验证码（合法）
                   如果获取到：把当时的存储时间获取到 根据当前时间减去 存储时间

                     k               v
                15008495702 -  123456:1626229048


        */
        //根据手机号获取redis里面的数据
        String codeInRedis = (String) redisTemplate.opsForValue().get(userVo.getCodeType()+":"+userVo.getPhone());
        if (codeInRedis!=null){ // codeInRedis=123456:1626229048
                //获取验证码存储的时间
                Long startTime =Long.valueOf(codeInRedis.split(":")[1]);
                //判断两次请求是否小于一分钟
                if((System.currentTimeMillis()-startTime)<60*1000){
                    throw  new RuntimeException("操作过于频繁，请稍后再试");
                }


        }

        //3.生成验证码
        String randomCode = StrUtils.getRandomString(6);

        if (codeInRedis!=null){//上一次的验证码还没有过期
            //获取验证码    codeInRedis=123456:1626229048
            randomCode= codeInRedis.split(":")[0];
        }
        //4.保存验证码
        /*
            目前的系统session 是不能使用，前端到后台 session是不一致的
            放到redis
             * @param key must not be {@literal null}.
             * @param value
             * @param timeout  过期时间
             * @param unit  单位
            以 手机号作为 key  验证码作为value  存储5分钟  单位为 分钟
            15008495702:656279  5分钟
         */
        String setCode = randomCode+":"+System.currentTimeMillis();

        // 以业务类型 + 手机号作为key   REGISTER:15008495702  或者 BINDER:15008495702
        redisTemplate.opsForValue().set(userVo.getCodeType()+":"+userVo.getPhone(),setCode
                ,5 , TimeUnit.MINUTES );
        System.out.println("本次的验证码为："+setCode);
        //5.调用第三方服务，验证码发送出去
        //SendMsgUtils.send(userVo.getPhone(), randomCode);
    }
}
